import socketio
import eventlet.wsgi
import socket  # 用于创建TCP socket连接
import eventlet
import threading

eventlet.monkey_patch()

# 打包成WSGI应用，使用WSGI服务器托管运行
sio = socketio.Server(async_mode='eventlet', cors_allowed_origins='*')  # 指明启动模式
app = socketio.Middleware(sio)

# 全局 TCP 客户端 socket
client_socket = None
tcp_server_address = ('172.17.0.2', 8812)  # 服务器地址和端口号

# 客户端列表
connected_clients = []


@sio.event
def audiomessage(sid, data):
    print(f"Message from {sid}: Received binary data of length {len(data)}")

    try:
        # 创建一个TCP/IP socket
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # 服务器地址和端口号
        server_address = ('172.17.0.2', 8816)

        # 连接服务器
        print(f"正在连接到服务器 {server_address}")
        client_socket.connect(server_address)

        try:
            # 发送数据
            print(f"发送: {len(data)}")
            client_socket.sendall(data)
            client_socket.shutdown(socket.SHUT_WR)

            # 等待接收服务器的响应
            ret = client_socket.recv(1024)
            print(f"收到服务器的回送: {ret}")

            # 将代理服务器的响应（base64编码后的二进制数据）发送回客户端 //sio.emit(event, data, room=None, skip_sid=None, namespace=None, callback=None)
            sio.emit('audio', {'data': ret.decode('utf-8')}, room=sid)
        finally:
            print("关闭连接")
            client_socket.close()

    except Exception as e:
        print(f"代理失败: {e}")
        sio.emit('audio', {'data': '代理请求失败'}, room=sid)
@sio.on('finalaudioresponse')
def handle_audio_response(sid, newdata):
    print(f"Message from {sid}: Received binary newdata of length {len(newdata)}")
    try:
        # 创建一个TCP/IP socket
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # 服务器地址和端口号
        server_address = ('172.17.0.2', 8817)

        # 连接服务器
        print(f"正在连接到服务器 {server_address}")
        client_socket.connect(server_address)

        try:
            # 发送数据
            print(f"发送: {len(newdata)}")
            client_socket.sendall(newdata.encode('utf-8'))
            client_socket.shutdown(socket.SHUT_WR)
        finally:
            print("关闭连接")
            client_socket.close()

    except Exception as e:
        print(f"代理失败: {e}")
        sio.emit('audio', {'data': '代理请求失败'}, room=sid)

# 在客户端连接时保存其ID
@sio.event
def connect(sid, environ):
    print(f"客户端 {sid} 已连接")
    connected_clients.append(sid)

# 在客户端断开连接时从列表移除
@sio.event
def disconnect(sid):
    print(f"客户端 {sid} 已断开连接")
    if sid in connected_clients:
        connected_clients.remove(sid)

# 建立与 TCP 服务器的连接
def connect_to_server():
    global client_socket
    try:
        # 创建一个TCP/IP socket
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # 连接服务器
        print(f"正在连接到服务器 {tcp_server_address}")
        client_socket.connect(tcp_server_address)
        client_socket.settimeout(2.0)  # 设置接收超时时间防止阻塞

    except Exception as e:
        print(f"无法连接到服务器: {e}")
        client_socket = None

# 后台任务：持续监听 TCP 服务器消息
def listen_to_tcp_server():
    global client_socket
    while True:
        if client_socket is None or client_socket._closed:
            print("TCP 连接未建立，重新连接...")
            connect_to_server()

        if client_socket:
            try:
                print("开始等待接收数据...")
                while True:
                    # 每次接收一个数据块
                    part = client_socket.recv(1024)
                    if not part:
                        print("TCP 连接关闭或无数据")
                        break

                    # 解码并发送给客户端
                    decoded_part = part.decode('utf-8')
                   # print(f"接收到数据块: {decoded_part}")
                    
                    # 每接收一个数据块，立即广播给所有客户端
                    broadcast_to_clients(decoded_part)

            except socket.timeout:
                print("接收数据超时，没有消息")
            except Exception as e:
                print(f"接收数据时发生错误: {e}")
                client_socket.close()
                client_socket = None

# 将消息广播给所有已连接的客户端
def broadcast_to_clients(message):
    for client in connected_clients:
       # print(f"准备向客户端 {client} 发送消息: {message}")
        sio.emit('response', {'data': message}, room=client)
        print(f"消息已发送给客户端 {client}")


# 启动 TCP 监听线程
def start_tcp_listener():
    tcp_listener_thread = threading.Thread(target=listen_to_tcp_server)
    tcp_listener_thread.daemon = True  # 设置为守护线程
    tcp_listener_thread.start()

def listen_to_udp():
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    udp_server_address = ('10.0.106.20', 5050)  # 监听所有 IP 上的 5050 端口
    udp_socket.bind(udp_server_address)
    print(f"UDP 服务器已启动，正在监听 {udp_server_address}...")

    while True:
        try:
            # 接收数据
            data, addr = udp_socket.recvfrom(1024)  
            print(f"从 {addr} 接收到 UDP 数据：{data}")

            # 直接通过 sio.emit 发送给所有已连接的客户端
            sio.emit('doglocation', {'data': data.decode('utf-8')})
            print("已通过 socketio 广播 UDP 数据给所有客户端")

        except Exception as e:
            print(f"UDP 接收错误: {e}")

# 启动 UDP 监听线程
def start_udp_listener():
    udp_listener_thread = threading.Thread(target=listen_to_udp)
    udp_listener_thread.daemon = True  # 设置为守护线程
    udp_listener_thread.start()

# 启动时连接到 TCP 服务器并启动监听
connect_to_server()
start_tcp_listener()
start_udp_listener()

# 启动 WSGI 服务器
eventlet.wsgi.server(eventlet.listen(('10.0.106.20', 8030)), app)
